home *** CD-ROM | disk | FTP | other *** search
- (*--------------------------------------------------------------------------*)
- (* Trim --- Trim trailing blanks from a string *)
- (*--------------------------------------------------------------------------*)
-
- FUNCTION Trim( S : AnyStr ) : AnyStr;
-
- (*--------------------------------------------------------------------------*)
- (* *)
- (* Function: Trim *)
- (* *)
- (* Purpose: Trims trailing blanks from a string *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Trimmed_S := TRIM( S ); *)
- (* *)
- (* S --- the string to be trimmed *)
- (* Trimmed_S --- the trimmed version of S *)
- (* *)
- (* Calls: None *)
- (* *)
- (* Remarks: *)
- (* *)
- (* Note that the original string itself is left untrimmed. *)
- (* *)
- (*--------------------------------------------------------------------------*)
-
- VAR
- I: INTEGER;
-
- BEGIN (* Trim *)
-
- I := ORD( S[0] );
-
- WHILE ( I > 0 ) AND ( S[I] = ' ' ) DO
- I := I - 1;
-
- S[0] := CHR( I );
- Trim := S;
-
- END (* Trim *);
-
- (*--------------------------------------------------------------------------*)
- (* Dupl -- Duplicate a character n times *)
- (*--------------------------------------------------------------------------*)
-
- FUNCTION Dupl( Dup_char : Char; Dup_Count: INTEGER ) : AnyStr;
-
- (*--------------------------------------------------------------------------*)
- (* *)
- (* Function: Dupl *)
- (* *)
- (* Purpose: Duplicate a character n times *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Dup_String := Dupl( Dup_Char: Char; Dup_Count: INTEGER ): AnyStr; *)
- (* *)
- (* Dup_Char --- Character to be duplicated *)
- (* Dup_Count --- Number of times to duplicate character *)
- (* Dup_String --- Resultant duplicated string *)
- (* *)
- (* Note: If Dup_Count <= 0, a null string is returned. *)
- (* *)
- (* Calls: None *)
- (* *)
- (* *)
- (* Remarks: *)
- (* *)
- (* This routine could be programmed directly in Turbo as: *)
- (* *)
- (* VAR *)
- (* S : AnyStr; *)
- (* *)
- (* BEGIN *)
- (* *)
- (* FillChar( S[1], Dup_Count, Dup_Char ); *)
- (* S[0] := CHR( Dup_Count ); *)
- (* *)
- (* Dupl := S; *)
- (* *)
- (* END; *)
- (* *)
- (*--------------------------------------------------------------------------*)
-
- BEGIN (* Dupl *)
-
- INLINE( $16/ (* PUSH SS ; Push stack ptr *)
- $07/ (* POP ES ; For result addressing *)
- $8B/$4E/$04/ (* MOV CX,[BP+4] ; Pick up dup count *)
- $88/$4E/$08/ (* MOV [BP+8],CL ; Store result length *)
- $8B/$46/$06/ (* MOV AX,[BP+6] ; Get char to duplicate *)
- $8D/$7E/$09/ (* LEA DI,[BP+9] ; Result address *)
- $FC/ (* CLD ; Set direction flag *)
- $F3/$AA (* REPLSTOSB ; Perform duplication *)
- );
-
- END (* Dupl *);
-
- (*----------------------------------------------------------------------*)
- (* Min --- Find minimum of two integers *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Min( A, B: INTEGER ) : INTEGER;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Min *)
- (* *)
- (* Purpose: Returns smaller of two numbers *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Smaller := MIN( A , B ) : INTEGER; *)
- (* *)
- (* A --- 1st input integer number *)
- (* B --- 2nd input integer number *)
- (* Smaller --- smaller of A, B returned *)
- (* *)
- (* *)
- (* Calls: None *)
- (* *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Min *)
-
- IF A < B Then
- Min := A
- Else
- Min := B;
-
- END (* Min *);
-
- (*----------------------------------------------------------------------*)
- (* Max --- Find maximum of two integers *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Max( A, B: INTEGER ) : INTEGER;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Max *)
- (* *)
- (* Purpose: Returns larger of two numbers *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Larger := MAX( A , B ) : INTEGER; *)
- (* *)
- (* A --- 1st input integer number *)
- (* B --- 2nd input integer number *)
- (* Larger --- Larger of A, B returned *)
- (* *)
- (* *)
- (* Calls: None *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Max *)
-
- IF A > B Then
- Max := A
- Else
- Max := B;
-
- END (* Max *);
-
- (*--------------------------------------------------------------------------*)
- (* Substr -- Get substring of a string *)
- (*--------------------------------------------------------------------------*)
-
- FUNCTION Substr( S : AnyStr; IS : INTEGER; NS: INTEGER ) : AnyStr;
-
- (*--------------------------------------------------------------------------*)
- (* *)
- (* Function: Substr *)
- (* *)
- (* Purpose: Takes substring of a string *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Sub_String := Substr( S: Anystr; *)
- (* IS: INTEGER; *)
- (* NS: INTEGER ): AnyStr; *)
- (* *)
- (* S --- String to get substring from *)
- (* IS --- Starting character in S of substring to extract *)
- (* NS --- Number of characters to extract *)
- (* *)
- (* Calls: Copy *)
- (* *)
- (* Remarks: *)
- (* *)
- (* This routine handles null strings which COPY doesn't like. *)
- (* *)
- (*--------------------------------------------------------------------------*)
-
- VAR
- L : INTEGER;
- L0: INTEGER;
-
- BEGIN (* Substr *)
- (* Keep all strings in proper range *)
- L0 := ORD( S[0] );
- L := L0 - IS + 1;
-
- IF( L < NS ) THEN
- NS := L;
- (* Extract substring or return null string *)
-
- IF ( NS <= 0 ) OR ( IS < 1 ) OR ( IS > L0 ) THEN
- Substr := ''
- ELSE
- Substr := COPY( S, IS, NS );
-
- END (* Substr *);
-
- (*--------------------------------------------------------------------------*)
- (* UpperCase --- Convert string to upper case *)
- (*--------------------------------------------------------------------------*)
-
- FUNCTION UpperCase( S: AnyStr ): AnyStr;
-
- (*--------------------------------------------------------------------------*)
- (* *)
- (* Function: UpperCase *)
- (* *)
- (* Purpose: Convert string to upper case *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Upper_String := UpperCase( S : AnyStr ): AnyStr; *)
- (* *)
- (* S --- String to be converted to upper case *)
- (* Upper_String --- Resultant uppercase string *)
- (* *)
- (* Calls: UpCase *)
- (* *)
- (* Remarks: *)
- (* *)
- (* This routine could be coded directly in Turbo as: *)
- (* *)
- (* VAR *)
- (* I : INTEGER; *)
- (* L : INTEGER; *)
- (* T : AnyStr; *)
- (* *)
- (* BEGIN *)
- (* *)
- (* L := ORD( S[0] ); *)
- (* *)
- (* FOR I := 1 TO L DO *)
- (* T[I] := UpCase( S[I] ); *)
- (* *)
- (* T[0] := CHR( L ); *)
- (* UpperCase := T; *)
- (* *)
- (* END; *)
- (* *)
- (*--------------------------------------------------------------------------*)
-
- BEGIN (* UpperCase *)
-
- INLINE( $1E/ (* PUSH DS ; Save DS *)
- $8A/$4E/$04/ (* MOV CL,[BP+4] ; Get length of S *)
- $30/$ED/ (* XOR CH,CH ; Clear CH *)
- $8D/$76/$05/ (* LEA SI,[BP+5] ; First source char *)
- $8D/$BE/$04/$01/ (* LEA DI,[BP+260] ; Result length *)
- $36/$88/$0D/ (* MOV SS[DI],CL ; Store length *)
- $80/$F9/$00/ (* CMP CL,0 ; Check for null *)
- $76/$18/ (* JLE L3 ; Quit if null *)
- $47/ (* INC DI ; First char result *)
- $8C/$D0/ (* MOV AX,SS ; Save stack addr *)
- $8E/$D8/ (* MOV DS,AX ; For source *)
- $8E/$C0/ (* MOV ES,AX ; For result *)
- $FC/ (* CLD ; Forward direction *)
- $8A/$04/ (* L1: MOV AL,[SI] ; Next source char *)
- $3C/$61/ (* CMP AL,'a' ; Compare with 'a' *)
- $72/$06/ (* JL L2 ; Below -- skip *)
- $3C/$7A/ (* CMP AL,'z' ; Compare with 'z' *)
- $77/$02/ (* JH L2 ; Above -- skip *)
- $2C/$20/ (* SUB AL,32 ; Uppercase letter *)
- $AA/ (* L2: STOSB ; Store in result *)
- $46/ (* INC SI ; Next char *)
- $E2/$F0/ (* LOOP L1 ; *)
- $1F (* L3: POP DS ; Restore DS *)
- );
-
- END (* UpperCase *);
-
- (*--------------------------------------------------------------------------*)
- (* Adjust_Hour --- Convert 24 hour time to 12 hour am/pm *)
- (*--------------------------------------------------------------------------*)
-
- PROCEDURE Adjust_Hour( VAR Hour : INTEGER;
- VAR AmPm : STRING2 );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Adjust_Hour *)
- (* *)
- (* Purpose: Converts 24 hour time to 12 hour am/pm time *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Adjust_Hour( VAR Hour : INTEGER; AmPm : String2 ); *)
- (* *)
- (* Hour --- Input = Hours in 24 hour form; *)
- (* Output = Hours in 12 hour form. *)
- (* AmPm --- Output 'am' or 'pm' indicator *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Adjust_Hour *)
-
- IF ( Hour < 12 ) THEN
- BEGIN
- AmPm := 'am';
- IF ( Hour = 0 ) THEN
- Hour := 12;
- END
- ELSE
- BEGIN
- AmPm := 'pm';
- IF ( Hour <> 12 ) THEN
- Hour := Hour - 12;
- END;
-
- END (* Adjust_Hour *);
-
- (*----------------------------------------------------------------------*)
- (* Convert_String_To_AsciiZ -- Convert Turbo string to Ascii Z String *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Convert_String_To_AsciiZ( VAR S: AnyStr );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Convert_String_To_AsciiZ *)
- (* *)
- (* Purpose: Convert Turbo string to ascii Z string *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Convert_String_To_AsciiZ( VAR S: AnyStr ); *)
- (* *)
- (* S --- Turbo string to be turned into Ascii Z string *)
- (* *)
- (* Calls: *)
- (* *)
- (* None *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Convert_String_To_AsciiZ *)
-
- S := S + CHR( 0 );
-
- END (* Convert_String_To_AsciiZ *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Set_Disk_Transfer_Address --- Set DMA address for disk I/O *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Dir_Set_Disk_Transfer_Address( VAR DMA_Buffer );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Dir_Set_Disk_Transfer_Address *)
- (* *)
- (* Purpose: Sets DMA address for disk transfers *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Dir_Set_Disk_Transfer_Address( VAR DMA_Buffer ); *)
- (* *)
- (* DMA_Buffer --- direct memory access buffer *)
- (* *)
- (* Calls: *)
- (* *)
- (* MsDos *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Dir_Reg: RegPack;
-
- BEGIN (* Dir_Set_Disk_Transfer_Address *)
-
- Dir_Reg.Ax := $1A00;
- Dir_Reg.Ds := SEG( DMA_Buffer );
- Dir_Reg.Dx := OFS( DMA_Buffer );
-
- MsDos( Dir_Reg );
-
- END (* Dir_Set_Disk_Transfer_Address *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Get_Default_Drive --- Get Default Drive *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Dir_Get_Default_Drive: CHAR;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Dir_Get_Default_Drive *)
- (* *)
- (* Purpose: Gets default drive for disk I/O *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Def_Drive := Dir_Get_Default_Drive : CHAR; *)
- (* *)
- (* Def_Drive --- Letter of default drive *)
- (* *)
- (* Calls: *)
- (* *)
- (* MsDos *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Dir_Reg: RegPack;
-
- BEGIN (* Dir_Get_Default_Drive *)
-
- Dir_Reg.Ah := $19;
-
- MsDos( Dir_Reg );
-
- Dir_Get_Default_Drive := CHR( Dir_Reg.Al + ORD( 'A' ) );
-
- END (* Dir_Get_Default_Drive *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Find_First_File --- Find First File Matching Given Specs *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Dir_Find_First_File( File_Pattern: AnyStr;
- VAR First_File : Directory_Record ):
- INTEGER;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Dir_Find_First_File *)
- (* *)
- (* Purpose: Find first file in directory matching specs *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Iok := Dir_Find_First_File( File_Pattern: AnyStr; *)
- (* VAR First_File : *)
- (* Directory_Record ): INTEGER; *)
- (* *)
- (* File_Pattern --- File pattern to look for. *)
- (* First_File --- First file matching specs. *)
- (* Iok --- 0 if file found, else MsDos return code. *)
- (* *)
- (* Calls: *)
- (* *)
- (* Dir_Set_Disk_Transfer_Address *)
- (* MsDos *)
- (* *)
- (* Remarks: *)
- (* *)
- (* The file pattern can be any standard MSDOS file pattern, *)
- (* including wildcards. For a complete directory list, enter *)
- (* '*.*' as the pattern. Use routine 'Dir_Find_Next_File' *)
- (* to get the remaining files. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Dir_Reg: RegPack;
-
- BEGIN (* Find_First_File *)
-
- Dir_Set_Disk_Transfer_Address( First_File );
-
- Convert_String_To_AsciiZ( File_Pattern );
-
- Dir_Reg.Ds := SEG( File_Pattern[1] );
- Dir_Reg.Dx := OFS( File_Pattern[1] );
- Dir_Reg.Ax := $4E00;
- Dir_Reg.Cx := $FF;
-
- MsDos( Dir_Reg );
-
- IF ( Carry_Flag AND Dir_Reg.Flags ) = 0 THEN
- Dir_Find_First_File := 0
- ELSE
- Dir_Find_First_File := Dir_Reg.Ax;
-
- END (* Find_First_File *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Find_Next_File --- Find Next File Matching Given Specs *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Dir_Find_Next_File ( VAR Next_File : Directory_Record ) : INTEGER;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Dir_Find_Next_File *)
- (* *)
- (* Purpose: Finds next file in directory matching specs *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Iok := Dir_Find_Next_File ( VAR Next_File : *)
- (* Directory_Record ) : INTEGER; *)
- (* *)
- (* Next_File --- Next file matching specs. *)
- (* Iok --- Returned as 0 if file found, else MsDos *)
- (* return code indicating error. *)
- (* *)
- (* Calls: *)
- (* *)
- (* MsDos *)
- (* Dir_Set_Disk_Transfer_Address *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Dir_Reg : RegPack;
-
- BEGIN (* Find_Next_File *)
-
- Dir_Set_Disk_Transfer_Address( Next_File );
-
- Dir_Reg.Ax := $4F00;
-
- MsDos( Dir_Reg );
-
- IF ( Carry_Flag AND Dir_Reg.Flags ) = 0 THEN
- Dir_Find_Next_File := 0
- ELSE
- Dir_Find_Next_File := Dir_Reg.Ax;
-
- END (* Find_Next_File *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Get_Free_Space --- Get free space in bytes on disk *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Dir_Get_Free_Space ( Drive : CHAR ) : REAL;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Dir_Get_Free_Space *)
- (* *)
- (* Purpose: Gets amount of available space on a drive *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* FSpace := Dir_Get_Free_Space ( Drive : CHAR ) : REAL; *)
- (* *)
- (* Drive --- Drive letter for which to get free space *)
- (* Fspace --- Returned number of bytes of free space *)
- (* *)
- (* Calls: *)
- (* *)
- (* MsDos *)
- (* *)
- (* Remarks: *)
- (* *)
- (* If the free space can't be found, -1 is returned. *)
- (* This is most likely to happen if an unformatted or wrongly *)
- (* formatted disk is to be checked. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Dir_Reg : RegPack;
- Clusters : REAL;
- Sectors : REAL;
- Bytes : REAL;
-
- BEGIN (* Dir_Get_Free_Space *)
-
- (* Request drive information *)
-
- Dir_Reg.DL := ORD(UpCase( Drive )) - ORD('A') + 1;
- Dir_Reg.AH := $36;
-
- MsDos( Dir_Reg );
-
- (* Compute free space *)
-
- WITH Dir_Reg DO
- BEGIN
-
- Sectors := AX;
- Clusters := BX;
- Bytes := CX;
-
- IF AX = $FFFF THEN
- Dir_Get_Free_Space := -1.0
- ELSE
- Dir_Get_Free_Space := Clusters * Bytes * Sectors;
-
- END;
-
- END (* Dir_Get_Free_Space *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Convert_Date --- Convert directory creation date *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Dir_Convert_Date ( Date : INTEGER; VAR S_Date : AnyStr );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Dir_Convert_Date *)
- (* *)
- (* Purpose: Convert creation date from directory to characters. *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Dir_Convert_Date( Date : INTEGER; *)
- (* VAR S_Date : AnyStr ) : INTEGER; *)
- (* *)
- (* Date --- date as read from directory *)
- (* S_Date --- converted date in yy/mm/dd *)
- (* *)
- (* Calls: *)
- (* *)
- (* STR *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- YY : String[2];
- MM : String[3];
- DD : String[2];
-
- BEGIN (* Dir_Convert_Date *)
-
- STR( ( 80 + ( Date SHR 9 ) ) : 2 , YY );
-
- MM := Month_Names[ ( Date AND $01E0 ) SHR 5 ];
-
- STR( ( Date AND $001F ):2 , DD );
-
- S_Date := DD + '-' + MM + '-' + YY;
-
- END (* Dir_Convert_Date *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Convert_Time --- Convert directory creation time *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Dir_Convert_Time ( Time : INTEGER; VAR S_Time : AnyStr );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Dir_Convert_Time *)
- (* *)
- (* Purpose: Convert creation time from directory to characters. *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* Dir_Convert_Time( Time : INTEGER; *)
- (* VAR S_Time : AnyStr ) : INTEGER; *)
- (* *)
- (* Time --- time as read from directory *)
- (* S_Time --- converted time in hh:mm:ss *)
- (* *)
- (* Calls: *)
- (* *)
- (* STR *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- HH : String[2];
- MM : String[2];
- AmPm : String[2];
- Hour : INTEGER;
-
- BEGIN (* Dir_Convert_Time *)
-
- Hour := ( Time SHR 11 );
-
- Adjust_Hour( Hour , AmPm );
-
- STR( Hour:2 , HH );
-
- STR( ( ( Time AND $07E0 ) SHR 5 ):2 , MM );
- IF MM[1] = ' ' THEN MM[1] := '0';
-
- S_Time := HH + ':' + MM + ' ' + AmPm;
-
- END (* Dir_Convert_Time *);
-
- (*----------------------------------------------------------------------*)
- (* Dir_Get_Volume_Label --- Get volume label of a disk *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Dir_Get_Volume_Label( Volume : CHAR;
- VAR Volume_Label : AnyStr;
- VAR Date : INTEGER;
- VAR Time : INTEGER );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Dir_Get_Volume_Label *)
- (* *)
- (* Purpose: Gets volume label for specified disk *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Dir_Get_Volume_Label( Volume : CHAR; *)
- (* VAR Volume_Label : AnyStr; *)
- (* VAR Date : INTEGER; *)
- (* VAR Time : INTEGER ); *)
- (* *)
- (* Volume --- Disk letter for which to get label *)
- (* Volume_Label --- Actual label itself *)
- (* Date --- Creation date of volume label *)
- (* Time --- Creation time of volume label *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Volume_Data : Directory_Record;
- Regs : RegPack;
- Volume_Pat : STRING[15];
-
- BEGIN (* Dir_Get_Volume_Label *)
-
- WITH Regs DO
- BEGIN
- (* Set up DMA address for volume info *)
-
- Dir_Set_Disk_Transfer_Address( Volume_Data );
-
- (* Search root directory for label *)
-
- Volume_Pat := Volume + ':*.*';
-
- Convert_String_To_AsciiZ( Volume_Pat );
-
- Regs.Ds := SEG( Volume_Pat[1] );
- Regs.Dx := OFS( Volume_Pat[1] );
- Regs.Ax := $4E00;
- Regs.Cx := Attribute_Volume_Label;
-
- (* Find volume label *)
- MsDos( Regs );
-
- IF ( Carry_Flag AND Regs.Flags ) <> 0 THEN
- BEGIN (* No volume label found *)
- Volume_Label := '';
- Date := 0;
- Time := 0;
- END
- ELSE
- WITH Volume_Data DO
- BEGIN (* Extract volume label *)
- Volume_Label := TRIM( COPY( File_Name, 1, POS( #0 , File_Name ) - 1 ) );
- Date := File_Date;
- Time := File_Time;
- END;
-
- END (* WITH *);
-
- END (* Dir_Get_Volume_Label *);
-
-
- (*--------------------------------------------------------------------------*)
- (* TimeOfDayString --- Return current time of day as string *)
- (*--------------------------------------------------------------------------*)
-
- FUNCTION TimeOfDayString : AnyStr;
-
- (*--------------------------------------------------------------------------*)
- (* *)
- (* Function: TimeOfDayString *)
- (* *)
- (* Purpose: Return current time of day as string *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Tstring := TimeOfDayString : AnyStr; *)
- (* *)
- (* Tstring --- Resultant 'HH:MM xx' form of time *)
- (* *)
- (*--------------------------------------------------------------------------*)
-
- VAR
- Hours : INTEGER;
- SH : STRING[2];
- SM : STRING[2];
- AmPm : STRING[2];
- Regs : RegPack;
-
- BEGIN (* TimeOfDayString *)
- (* Time of day interrupt *)
- Regs.Ax := $2C00;
- INTR( $21 , Regs );
-
- Hours := Regs.Ch;
-
- Adjust_Hour( Hours , AmPm );
-
- STR( Hours :2, SH );
- STR( Regs.Cl:2, SM );
-
- IF SM[1] = ' ' THEN SM[1] := '0';
-
- TimeOfDayString := SH + ':' + SM + ' ' + AmPm;
-
- END (* TimeOfDayString *);
-
- (*--------------------------------------------------------------------------*)
- (* DateString --- Return current date in string form *)
- (*--------------------------------------------------------------------------*)
-
- FUNCTION DateString : AnyStr;
-
- (*--------------------------------------------------------------------------*)
- (* *)
- (* Function: DateString *)
- (* *)
- (* Purpose: Returns current date in string form *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Dstring := DateString: AnyStr; *)
- (* *)
- (* Dstring --- Resultant string form of date *)
- (* *)
- (* Calls: MsDos *)
- (* *)
- (*--------------------------------------------------------------------------*)
-
- VAR
- RecPack: RegPack;
- Month: STRING[3];
- Day: STRING[2];
- Year: STRING[2];
-
- BEGIN (* DateString *)
- (* Date function *)
- RecPack.Ax := $2A00;
- (* Get date from DOS *)
- MsDos( RecPack );
- (* Convert to MM/DD/YY string *)
- WITH Recpack DO
- BEGIN
- STR( Cx - 1900 :2 , Year );
- STR( Dx MOD 256:2 , Day );
- Month := Month_Names[ Dx SHR 8 ];
- END;
-
- DateString := Day + '-' + Month + '-' + Year;
-
- END (* DateString *);
-
- (*----------------------------------------------------------------------*)
- (* Long_To_Real --- Convert 32 bit INTEGER to real *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION Long_To_Real( Long : LongInt ) : REAL;
-
- VAR
- RLow : REAL;
- RHigh: REAL;
-
- BEGIN (* Long_To_Real *)
-
- WITH Long DO
- BEGIN
- (* Convert low-order 16 bits *)
- IF ( Low < 0 ) THEN
- RLow := 65536.0 + Low
- ELSE
- RLow := Low;
- (* Convert high-order 16 bits *)
- IF ( High < 0 ) THEN
- RHigh := 65536.0 + High
- ELSE
- RHigh := High;
-
- END;
- (* Put 'em together! *)
-
- Long_To_Real := RHigh * 65536.0 + RLow;
-
- END (* Long_To_Real *);
-
- (*----------------------------------------------------------------------*)
- (* Open_File --- Open untyped file for processing *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Open_File( FileName : AnyStr;
- VAR AFile : FILE;
- VAR File_Pos : REAL;
- VAR Error : INTEGER );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Open_File *)
- (* *)
- (* Purpose: Opens untyped file (of byte) for input *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Open_File( FileName : AnyStr; *)
- (* VAR AFile : FILE; *)
- (* VAR File_Pos : REAL; *)
- (* VAR Error : INTEGER ); *)
- (* *)
- (* FileName --- Name of file to open *)
- (* AFile --- Associated file variable *)
- (* File_Pos --- Initial byte offset in file (always set to 0) *)
- (* Error --- = 0: Open went OK. *)
- (* <> 0: Open failed. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Open_File *)
- (* Try opening file. Access *)
- (* is essentially as file of byte. *)
- (*$I-*)
- ASSIGN( AFile , FileName );
- RESET ( AFile , 1 );
- (*$I+*)
- (* Check if open went OK or not *)
- IF ( IOResult <> 0 ) THEN
- Error := Open_Error
- ELSE
- Error := 0;
- (* We are at beginning of file *)
- File_Pos := 0.0;
-
- END (* Open_File *);
-
- (*----------------------------------------------------------------------*)
- (* Close_File --- Close an unytped file *)
- (*----------------------------------------------------------------------*)
-
- PROCEDURE Close_File( VAR AFile : FILE );
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Procedure: Close_File *)
- (* *)
- (* Purpose: Closes untyped file *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Close_File( VAR AFile : FILE ); *)
- (* *)
- (* AFile --- Associated file variable *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- BEGIN (* Close_File *)
- (* Close the file *)
- (*$I-*)
- CLOSE( AFile );
- (*$I+*)
- (* Clear error flag *)
- IF ( IOResult <> 0 ) THEN;
-
- END (* Close_File *);
-
- (*----------------------------------------------------------------------*)
- (* Quit_Found --- Check if ^C hit on keyboard *)
- (*----------------------------------------------------------------------*)
-
- FUNCTION QuitFound : BOOLEAN;
-
- (*----------------------------------------------------------------------*)
- (* *)
- (* Function: Quit_Found *)
- (* *)
- (* Purpose: Determines if keyboard input is ^C *)
- (* *)
- (* Calling sequence: *)
- (* *)
- (* Quit := Quit_Found : BOOLEAN; *)
- (* *)
- (* Quit --- TRUE if ^C typed at keyboard. *)
- (* *)
- (* Remarks: *)
- (* *)
- (* The cataloguing process can be halted by hitting ^C at the *)
- (* keyboard. This routine is called when Find_Files notices that *)
- (* keyboard input is waiting. If ^C is found, then cataloguing *)
- (* stops at the next convenient breakpoint. The global variable *)
- (* User_Break indicates that a ^C was found. *)
- (* *)
- (*----------------------------------------------------------------------*)
-
- VAR
- Ch : CHAR;
-
- BEGIN (* QuitFound *)
- (* Character was hit -- read it *)
- READ( Kbd, Ch );
- (* If it is a ^C, set User_Break *)
- (* so we halt at next convenient *)
- (* location. *)
-
- User_Break := User_Break OR ( Ch = ^C );
- QuitFound := User_Break;
- (* Purge anything else in keyboard *)
- (* buffer *)
- WHILE( KeyPressed ) DO
- READ( Kbd, Ch );
-
- END (* QuitFound *);